package com.hyt.it.ogt.kq.service.gov.schedule.strategy;

import com.hyt.it.ogt.kq.service.gov.schedule.impl.ExamRoomScheduleImpl;
import com.hyt.it.ogt.kq.service.gov.schedule.model.ExamRoom;
import com.hyt.it.ogt.kq.service.gov.schedule.model.ScheduleConstrain;
import com.hyt.it.ogt.kq.service.gov.schedule.model.ScheduleRecord;
import com.hyt.it.ogt.kq.service.gov.schedule.utils.ScheduleUtils;
import com.hyt.it.ogt.kq.service.gov.schedule.utils.SupportUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class ScheduleBalanceStrategy implements ScheduleStrategy {
    private static final Logger logger = LoggerFactory.getLogger(ScheduleBalanceStrategy.class);
    private static ScheduleBalanceStrategy scheduleBalanceStrategy;

    public static ScheduleBalanceStrategy getInstance() {
        if (scheduleBalanceStrategy == null) {
            scheduleBalanceStrategy = new ScheduleBalanceStrategy();
        }
        return scheduleBalanceStrategy;
    }

    /****
     * 按考场容量从大到小进行排序，填充考场考生
     */
    @Override
    public List<ScheduleRecord> schedule(ScheduleConstrain scheduleConstrain, String groupName,
                                         List<String> batchNoList,
                                         List<ExamRoom> examRooms, List<String> virCandidateIds) {
        /*
        Map<String, Map<String, String>> virId2CandidateIdMap = ScheduleHelper.getInstance().getVirId2CandidateIdMap();
        virCandidateIds.forEach(item -> {
            Map<String, String> map = virId2CandidateIdMap.computeIfAbsent(item, k -> new HashMap<>());
            Set<String> missingBatchNos = batchNoList.stream()
                    .filter(batchStr -> !map.containsKey(batchStr))
                    .collect(Collectors.toSet());
            missingBatchNos.forEach(batchStr -> map.put(batchStr, ""));
        });*/

        List<ExamRoom> sortedExamRooms = examRooms.stream()
                .sorted(Comparator.comparing(ExamRoom::getCapacity).reversed())
                .collect(Collectors.toList());

        if("1".equals(scheduleConstrain.arrangeConfig)){
            int count = 0;
            for(ExamRoom room : sortedExamRooms){
                count += room.getCapacity();
            }
            if(virCandidateIds.size() < count && count > 0){
                double num = virCandidateIds.size();
                double percent = num / count;
                int lastRoomCapacity = virCandidateIds.size();
                for(int i = 0; i < sortedExamRooms.size(); i++){
                    ExamRoom room =  sortedExamRooms.get(i);
                    int capacity = (int) Math.round(room.getCapacity()* percent);
                    if (capacity > room.getCapacity()) {
                        capacity = room.getCapacity();
                    }
                    room.setCapacity(capacity);
                    if(i  != sortedExamRooms.size() - 1){
                        lastRoomCapacity -= capacity;
                    } else {
                        room.setCapacity(lastRoomCapacity);
                    }
                    room.getIdlePosition().clear();
                    room.getIdlePosition()
                            .addAll(IntStream.rangeClosed(1, room.getCapacity()).boxed().collect(Collectors.toList()));
                }
            }
        }

        List<ScheduleRecord> scheduleRecords = this.fillExamRoom(scheduleConstrain, sortedExamRooms, virCandidateIds);
        return scheduleRecords;
    }


}
